package com.mocha.auth.service;

import cn.hutool.core.util.ArrayUtil;
import com.coffee.security.CoffeeAuthUser;
import com.coffee.security.CoffeeUser;
import com.coffee.security.SecurityConstants;
import org.springframework.core.Ordered;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.*;

/**
 * @author songkui
 * @since 2025-4-17
 */
public interface CoffeeUserDetailsService extends UserDetailsService, Ordered {

	default UserDetails loadUserDetails(String username, String clientId){
		String usernameKey = String.format("%s:%s", clientId , username) ;
		return this.loadUserByUsername(usernameKey);
	}

    /**
     * 是否支持此客户端校验
     *
     * @param clientId 目标客户端
     * @return true/false
     */
    default boolean support(String clientId, String grantType) {
        return true;
    }

    /**
     * 排序值 默认取最大的
     *
     * @return 排序值
     */
    default int getOrder() {
        return 0;
    }

    /**
     * 构建 UserDetails
     */
    default UserDetails getUserDetails(CoffeeUser user) {
        Optional.ofNullable(user).orElseThrow(() -> new UsernameNotFoundException("User not found"));

        Set<String> dbAuthsSet = new HashSet<>();
        if (ArrayUtil.isNotEmpty(user.getRoleIds())) {
            // 获取角色
            Arrays.stream(user.getRoleIds()).forEach(role -> dbAuthsSet.add(SecurityConstants.ROLE + role));
            // 获取资源
            dbAuthsSet.addAll(Arrays.asList(user.getPermissions()));

        }

        Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(dbAuthsSet.toArray(new String[0]));
        //   id,  deptId,  nickname,  username,   password,  mobile
        return new CoffeeAuthUser(user.getId(), user.getDeptId(), user.getNickname(), user.getUsername(), SecurityConstants.BCRYPT + user.getPassword(), user.getMobile(), user.getClientId(), user.getTenantId(),
                true, true, true, user.isLockedFlag(), authorities);
    }


}
